Food Consumption 🔬

[1]

Projekt ten przedstawia mój tok myślenia oraz opinie! Wersja z czystą analizą dostępna jest na:

Jako osoba która pracowała na kuchni i interesuje się nią i tematami ją otaczającymi, w tym notatniku zajmę się analizą bazy danych z WHO na temat konsumpcji produktów na świecie. Moim planem jest odpowiedziec na pytanie, jakie produkty są najpopularniejsze, na co to wskazuje, jakie są różnice między kobietami i mężczyznami oraz jak te dane można by wykorzystać tworząc menu do restauracji. Myślę, że bardzo ciekawe informacje będzie można wyciągnąć z tych danych i będą one pomocne przy tworzeniu menu do restauracji.¶

📝 Plan jest następujący:¶

  1. Sprawdzenie jak skonstruowana jest baza danych, jakie informacje i typy danych znajdują sie w kolumnach. Niby łatwy krok ale bardzo ważny bo wiedza o bazie danych to podstawa dobrej analizy.
  2. Z tą wiedzą pozbędę się kolumn które na pewno nie będą mi potrzebne.
  3. Następnie sprawdzę gdzie znajdują sie puste dane oraz gdzie jest największe ryzyko ich znajdowania się, a potem pozbędę sie ich
  4. Potem sprawdzę z jakich krajów i kontynentów jest najwięcej danych, żeby ocenić ich używalnośc w globalnej skali
  5. Kolejną rzeczą będzie wyciagniecie danych dla produktów spożywanych na całym świecie, w Europie oraz to samo dla mężczyzn i kobiet na świecie i Europie.
  6. Na koniec będzie podsumowanie tego co udało się osiągnąć, jakie były wyzwania, problemy, błędy, sukcesy ### Taki jest plan ale co napotkam na tej drodze to się okaże. Liczę na to że będzie ciekawie!

Spis treści: 📕

  1. Wczytywanie danych
  2. Usuwanie niepotrzebnych kolumn
  3. Usuwanie duplikatów i pustych danych
  4. Wykres: Ilośc badanych dla krajów
    1. Wnioski
  5. Tworzenie kolumn z kodami i nazwami kontynentów
  6. Wykres: Procentowy udział badanych patrząc na kontynent
    1. Wnioski
  7. Wykres: Najpopularniejsze produkty na Świecie
    1. Wnioski
  8. Wykres: Najpopularniejsze produkty w Europie
    1. Wnioski
  9. Wykresy: Najpopularniejsze produkty dla mężczyzn i kobiet na Świecie
    1. Wnioski
  10. Wykresy: Najpopularniejsze produkty dla mężczyzn i kobiet w Europie
    1. Wnioski
  11. Podsumowanie
  12. Możliwe zakłamania
  13. Źródła
In [1]:
# import bibliotek oraz ustawienia
import pandas as pd
import missingno as msno
import matplotlib.pyplot as plt
import pycountry_convert as pc
import plotly.express as px
from plotly.subplots import make_subplots
import plotly.graph_objects as go
plt.style.use('fivethirtyeight')

Wczytywanie danych ↑ [2]

In [2]:
food = pd.read_csv("fullcifocoss.csv", on_bad_lines='skip', sep=';', skipinitialspace = True)  # wczytanie danych do dataframe pozbywając sie rzędów, które mają za dużo pól oraz spacji
pd.set_option('display.max_columns', None) # sprawiam że można przejrzeć wszystkie columny ponieważ by deafault jest ograniczona ilość wyświetlanych kolumn
food.head()
Out[2]:
BW Country Year FoodCode FoodName AgeClass SourceAgeClass Gender Number_of_consumers Consumers_Mean Consumers_Median Consumers_P05 Consumers_P90 Consumers_P95 Consumers_P975 Consumers_Standard_deviation Number_of_subjects Total_Mean Total_Median Total_P05 Total_P90 Total_P95 Total_P975 Total_Standard_deviation ExtBW ExtBWValue
0 0 China 2002 A000G Oat grain All All All 1157 60.6230 0.0 8.3333 116.6667 150.0000 166.6667 NaN 66172 1.0600 0.0 0.0 NaN 0.0 NaN NaN NaN NaN
1 0 China 2002 A000G Oat grain All All female 608 55.8676 0.0 8.3333 116.6667 133.3333 158.3333 NaN 33953 1.0004 0.0 0.0 NaN 0.0 NaN NaN NaN NaN
2 0 China 2002 A000G Oat grain All All male 549 65.8895 0.0 10.0000 133.3333 158.3333 166.6667 NaN 32219 1.1227 0.0 0.0 NaN 0.0 NaN NaN NaN NaN
3 0 China 2002 A000N Buckwheat All All All 167 55.2645 0.0 8.3333 100.0000 116.6667 158.3333 NaN 66172 0.1395 0.0 0.0 NaN 0.0 NaN NaN NaN NaN
4 0 China 2002 A000N Buckwheat All All female 82 54.7053 0.0 8.3333 83.3333 116.6667 183.3333 NaN 33953 0.1321 0.0 0.0 NaN 0.0 NaN NaN NaN NaN

Usuwanie niepotrzebnych kolumn ↑

In [3]:
food.drop(columns=food.loc[:, 'Consumers_P05':'Consumers_Standard_deviation'], inplace=True)
food.drop(columns=food.loc[:, 'Total_P05':'ExtBWValue'], inplace=True)
food = food.drop(['BW'], axis=1)
food.head(10)
Out[3]:
Country Year FoodCode FoodName AgeClass SourceAgeClass Gender Number_of_consumers Consumers_Mean Consumers_Median Number_of_subjects Total_Mean Total_Median
0 China 2002 A000G Oat grain All All All 1157 60.6230 0.0 66172 1.0600 0.0
1 China 2002 A000G Oat grain All All female 608 55.8676 0.0 33953 1.0004 0.0
2 China 2002 A000G Oat grain All All male 549 65.8895 0.0 32219 1.1227 0.0
3 China 2002 A000N Buckwheat All All All 167 55.2645 0.0 66172 0.1395 0.0
4 China 2002 A000N Buckwheat All All female 82 54.7053 0.0 33953 0.1321 0.0
5 China 2002 A000N Buckwheat All All male 85 55.8039 0.0 32219 0.1472 0.0
6 China 2002 A000P Barley grains All All All 61 38.5792 0.0 66172 NaN 0.0
7 China 2002 A000P Barley grains All All female 28 37.5000 0.0 33953 NaN 0.0
8 China 2002 A000P Barley grains All All male 33 39.4949 0.0 32219 NaN 0.0
9 China 2002 A000T Maize grain All All All 2422 86.9653 0.0 66172 3.1831 0.0
In [4]:
food.shape
Out[4]:
(544686, 13)

Ustawię jeszcze, żeby na pewno wszystkie liczby miały 2 liczby po przecinku, bo wolę taki wygląd, a wrazie potrzeb, zawsze mogę wrócić do deafaultowych ustawień.¶

In [5]:
pd.set_option('display.float_format', lambda x: '%.2f' % x)
food.head()
Out[5]:
Country Year FoodCode FoodName AgeClass SourceAgeClass Gender Number_of_consumers Consumers_Mean Consumers_Median Number_of_subjects Total_Mean Total_Median
0 China 2002 A000G Oat grain All All All 1157 60.62 0.00 66172 1.06 0.00
1 China 2002 A000G Oat grain All All female 608 55.87 0.00 33953 1.00 0.00
2 China 2002 A000G Oat grain All All male 549 65.89 0.00 32219 1.12 0.00
3 China 2002 A000N Buckwheat All All All 167 55.26 0.00 66172 0.14 0.00
4 China 2002 A000N Buckwheat All All female 82 54.71 0.00 33953 0.13 0.00

Usuwanie duplikatów i pustych danych. ↑

In [6]:
food.shape
Out[6]:
(544686, 13)
In [7]:
food = food.drop_duplicates()
In [8]:
food.shape
Out[8]:
(523276, 13)
In [9]:
544686-523276 
Out[9]:
21410

Pozbyłem się tym prostym sposobem 21410 duplikatów.¶

Przy użyciu biblioteki missingno oraz metody isna sprawdzam, gdzie znajdują sie puste dane.¶

In [10]:
msno.bar(food)
Out[10]:
<Axes: >
In [11]:
food.isna().sum()
Out[11]:
Country                   0
Year                      0
FoodCode                 20
FoodName                624
AgeClass                  0
SourceAgeClass            0
Gender                    0
Number_of_consumers       0
Consumers_Mean           32
Consumers_Median       4532
Number_of_subjects        0
Total_Mean             5102
Total_Median              3
dtype: int64

Zarówno na wykresie jak i w tabeli widać, że FoodName i FoodCode mają puste wartości (na razie nie zajmuję sie innymi kolumnami z pustymi watościami, bo nie wiem czy będą użyteczne), wiec zajmuję sie usunięciem tych rzędów.¶

In [12]:
null_data = food[food.isnull().any(axis=1)]
null_data.tail(5) # NaN w FoodCode widać dopiero na 50 ale dla wygody pozostaje default
Out[12]:
Country Year FoodCode FoodName AgeClass SourceAgeClass Gender Number_of_consumers Consumers_Mean Consumers_Median Number_of_subjects Total_Mean Total_Median
540608 Republic of Korea 2015 fa6adbfab52e8a77f23df411f59c2150 NaN Children and Adolescents 3-5 years All 692 2.26 0.84 804 1.95 0.59
540609 Republic of Korea 2015 fa6adbfab52e8a77f23df411f59c2150 NaN Children and Adolescents 6-14 years All 1937 1.89 0.81 2376 1.54 0.48
540610 Republic of Korea 2015 fa6adbfab52e8a77f23df411f59c2150 NaN Adults and Elderly 15-49 years All 6798 1.80 0.76 8253 1.48 0.48
540611 Republic of Korea 2015 fa6adbfab52e8a77f23df411f59c2150 NaN Adults and Elderly 50-74 years All 6054 2.04 0.76 7069 1.74 0.49
540612 Republic of Korea 2015 fa6adbfab52e8a77f23df411f59c2150 NaN Adults and Elderly >75 years All 1204 1.97 0.40 1650 1.44 0.11
In [13]:
food.loc[527540]
Out[13]:
Country                Democratic Republic of the Congo
Year                                               2016
FoodCode                                            NaN
FoodName                                            NaN
AgeClass                                            All
SourceAgeClass                                      All
Gender                                              All
Number_of_consumers                                   1
Consumers_Mean                                     3.36
Consumers_Median                                   3.36
Number_of_subjects                                  214
Total_Mean                                         0.02
Total_Median                                       0.00
Name: 527540, dtype: object

Tutaj widzimy że w FoodName i FoodCode puste dane są opisane jako NaN . Dodatkowo jest jeszcze długi kod, który jest dłuższy od innych które widziałem i jest taki sam w każdym rzędzie, gdzie są puste dane, także usunę FoodName i zobaczę czy nadal te kody pozostały, jeżeli one nie opisują żadnego produktu to one także zostaną usunięte. Prawdopodobnie własnie z powodu błędnego kodu produktu nie ma nazwy produktu.¶

In [14]:
food = food.dropna(subset=['FoodName'])
In [15]:
food.isna().sum()      
Out[15]:
Country                   0
Year                      0
FoodCode                  0
FoodName                  0
AgeClass                  0
SourceAgeClass            0
Gender                    0
Number_of_consumers       0
Consumers_Mean           32
Consumers_Median       4532
Number_of_subjects        0
Total_Mean             5102
Total_Median              3
dtype: int64

Wychodzi że nie ma już pustych danych. Poprzez usuwanie pustych danych w FoodName pozbyłem się również pustych danych z FoodCode, co znaczy, że tylko po części było to zależne od długości kodu i mogą być długie kody które działają. Jednak jeszcze trzeba sprawdzić czy produkty które miały kod fa6adbfab52e8a77f23df411f59c2150 też zostały usunięte, wstępnie z tego co widać poprawne kody nie są dłuższe niz 5 znaków, także sprawdzam czy istnieją dłuższe kody w kolumnie FoodCode.¶

In [16]:
food.loc[food['FoodCode'] == "fa6adbfab52e8a77f23df411f59c2150"]
Out[16]:
Country Year FoodCode FoodName AgeClass SourceAgeClass Gender Number_of_consumers Consumers_Mean Consumers_Median Number_of_subjects Total_Mean Total_Median
In [17]:
temp = food['FoodCode'].str.len() > 5
temp.value_counts()
Out[17]:
FoodCode
False    516640
True       6012
Name: count, dtype: int64

Wygląda na to, że tego konkretnego kodu sie pozbyłem ale kody, których długoś jest większa od 5 nadal istnieją i pytanie czy one są poprawne czy nie.¶

In [18]:
checkpoint = food #tworzę checkpoint żeby móc łatwo wrócić do wersji przed sortowaniem
food['CodeLen'] = food['FoodCode'].str.len()
food.sort_values(by=['CodeLen'])
Out[18]:
Country Year FoodCode FoodName AgeClass SourceAgeClass Gender Number_of_consumers Consumers_Mean Consumers_Median Number_of_subjects Total_Mean Total_Median CodeLen
0 China 2002 A000G Oat grain All All All 1157 60.62 0.00 66172 1.06 0.00 5
348298 Portugal 2015 A00DH Oat rolled grains Children and Adolescents Other children Female 1 0.40 0.40 262 0.00 0.00 5
348297 Portugal 2015 A006R Traditional unleavened breads Children and Adolescents Other children Female 1 1.94 1.94 262 0.01 0.00 5
348296 Portugal 2015 A006P Rusk, wholemeal Children and Adolescents Other children Male 1 1.63 1.63 259 0.01 0.00 5
348295 Portugal 2015 A006P Rusk, wholemeal Children and Adolescents Other children Female 4 0.65 0.59 262 0.01 0.00 5
... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
251182 Nigeria 2011 17348df7c5044de2950b5bce2d8bb912 (All Meat and meat products) Children and Adolescents 6-14 years female 0 0.00 0.00 1 0.00 0.00 32
275702 United States of America 2010 356d09ef45eb5879c5a334a1b9441094 (All Ingredients) Adults and Elderly >75 years All 1429 0.10 0.08 1595 0.09 0.07 32
275701 United States of America 2010 356d09ef45eb5879c5a334a1b9441094 (All Ingredients) Adults and Elderly 50-74 years All 4496 0.11 0.08 5215 0.10 0.06 32
275699 United States of America 2010 356d09ef45eb5879c5a334a1b9441094 (All Ingredients) Children and Adolescents 6-14 years All 3215 0.07 0.04 4330 0.05 0.02 32
217932 Italy 2006 eb31155c944a8c91ec4a53503cf50264 (All Nuts) Adults and Elderly 15-49 years female 56 14.83 11.20 873 0.95 0.00 32

522652 rows × 14 columns

In [19]:
temp = food.loc[food['FoodCode'] == "a93a0316b93a7c2af9305e90012af119"]
len(temp)
Out[19]:
458

Wygląda na to, że nie wszystkie kody o dlugości 32 są błędne, więc sama długość nie jest powodem pustych danych.¶

Teraz sprawdzę czy wszystkie grupy wiekowe i ilość konsumentów składają się na grupę wiekową All. Dla wygody użyję tylko danych dla owsa i Chin.¶

In [20]:
food = checkpoint # powrót do checkpointa
food_all = food.loc[food['Gender'] == "All"]
food_all_oat = food_all.loc[food_all['FoodName'] == "Oat grain"]
food_all_oat_ch = food_all_oat.loc[food_all_oat['Country'] == "China"]

food_all_oat_ch.head(20)
Out[20]:
Country Year FoodCode FoodName AgeClass SourceAgeClass Gender Number_of_consumers Consumers_Mean Consumers_Median Number_of_subjects Total_Mean Total_Median CodeLen
0 China 2002 A000G Oat grain All All All 1157 60.62 0.00 66172 1.06 0.00 5
812 China 2002 A000G Oat grain Infants and Toddlers 0-35 months All 10 28.58 0.00 838 0.34 0.00 5
1251 China 2002 A000G Oat grain Children and Adolescents 3-5 years All 20 22.00 0.00 2235 0.20 0.00 5
1782 China 2002 A000G Oat grain Children and Adolescents 6-14 years All 107 39.97 0.00 9844 0.43 0.00 5
2487 China 2002 A000G Oat grain Adults and Elderly 15-49 years All 545 66.67 0.00 33719 1.08 0.00 5
3267 China 2002 A000G Oat grain Adults and Elderly 50-74 years All 438 62.06 0.00 18143 1.50 0.00 5
4020 China 2002 A000G Oat grain Adults and Elderly >75 years All 37 43.87 0.00 1393 1.17 0.00 5
279440 China 2002 A000G Oat grain All All All 1157 1.12 NaN 66172 NaN 0.00 5
280252 China 2002 A000G Oat grain Infants and Toddlers 0-35 months All 10 2.00 NaN 838 NaN 0.00 5
280691 China 2002 A000G Oat grain Children and Adolescents 3-5 years All 20 1.31 NaN 2235 NaN 0.00 5
281222 China 2002 A000G Oat grain Children and Adolescents 6-14 years All 107 1.35 NaN 9844 NaN 0.00 5
281927 China 2002 A000G Oat grain Adults and Elderly 15-49 years All 545 1.12 NaN 33719 NaN 0.00 5
282707 China 2002 A000G Oat grain Adults and Elderly 50-74 years All 438 1.06 NaN 18143 NaN 0.00 5
283460 China 2002 A000G Oat grain Adults and Elderly >75 years All 37 0.79 NaN 1393 NaN 0.00 5

Już teraz widać ze są problemy. Dane się powtarzają, ale nie we wszystkich kolumnach. W przypadku grupy wiekowej All, Number_of_consumers i Number_of_subjects mają takie same liczby, ale inne kolumny albo nie maja danych albo maja inne wartośći. Znaczy to, że są tu powielone rzędy i trzeba pozbyć sie tych duplikatów. Wygląda na to, że najlepszym sposobem byłoby zrobienie tego, usuwając rzędy w których jest NaN w Consumers_Median i Total_Mean tylko pytanie czy te kolumny są wiarygodne, wiec trzeba sprawdzić czy te liczby są prawdziwe, a jako że nie ma legendy o tym jak dokładnie są otrzymane te wartości i co na pewno znaczą to sam spróbuje to zrozumieć, a jeżeli nie będą one dawać poprawnych wyników to zostaną usunięte.¶

In [21]:
food_all_oat_ch['Consumers_Mean'].iloc[0] 
Out[21]:
60.623
In [22]:
1157/66172*100 # procent konsumentów z całej puli badanych 
Out[22]:
1.748473674666022
In [23]:
66172/1157 #liczba badanych podzielona przez liczbę konsumentów
Out[23]:
57.19273984442524
In [24]:
(1.12+66172)/1157 # połączona liczba badanych podzielona przez liczbę konsumentów
Out[24]:
57.193707865168534
In [25]:
food_all_oat_ch['Consumers_Mean'].iloc[1:7].sum() # suma średnich dla rzędów 1-6
Out[25]:
263.15090000000004
In [26]:
food_all_oat_ch['Consumers_Mean'].iloc[1:7].mean() # średnia ze średnich
Out[26]:
43.85848333333334
In [27]:
food_all_oat_ch['Number_of_consumers'].iloc[:7].mean() # średnia z pierwszyć 7 rzędów
Out[27]:
330.57142857142856
In [28]:
food_all_oat_ch['Number_of_consumers'].iloc[0]/food_all['Number_of_consumers'].iloc[1:7].sum() # wartość dla all podzielona przez sume wartości rzędów 1-6
Out[28]:
0.01670516892867456

Żadne obliczenia nie daja takiej wartości jaka jest w kolumnie Consumers_Mean, więc albo są to jakieś inne dane, np średnia ilość gramów spożywanego produktu przez ankietowanych albo coś zupełnie innego, ale bez odpowiedniej wiedzy nie można tego założyć. Znaczy to, że trzeba sie pozbyć tych kolumn, gdyż nawet gdyby pomocne, mogą one zawierać fałszywe wartości.¶

Uswam więc: Consumers_Mean, Consumers_Median, Total_Mean, Total_Median i dodatkowo CodeLen które i tak już nie będzie użyteczne dla mnie.¶

In [29]:
food.shape
Out[29]:
(522652, 14)
In [30]:
food = food.drop(['Consumers_Mean', 'Consumers_Median', 'Total_Mean', 'Total_Median', 'CodeLen'], axis=1)
food.shape
Out[30]:
(522652, 9)
In [31]:
food
Out[31]:
Country Year FoodCode FoodName AgeClass SourceAgeClass Gender Number_of_consumers Number_of_subjects
0 China 2002 A000G Oat grain All All All 1157 66172
1 China 2002 A000G Oat grain All All female 608 33953
2 China 2002 A000G Oat grain All All male 549 32219
3 China 2002 A000N Buckwheat All All All 167 66172
4 China 2002 A000N Buckwheat All All female 82 33953
... ... ... ... ... ... ... ... ... ...
544675 Republic of Korea 2015 A16MR Juice concentrate, pineapple Adults and Elderly 15-49 years male 1 3518
544679 Republic of Korea 2015 A16MR Juice concentrate, pineapple All All male 1 9114
544680 Republic of Korea 2015 A16MR Juice concentrate, pineapple All All female 2 11557
544684 Republic of Korea 2015 A16MR Juice concentrate, pineapple Adults and Elderly 15-49 years All 1 8253
544685 Republic of Korea 2015 A16MR Juice concentrate, pineapple Adults and Elderly 50-74 years All 2 7069

522652 rows × 9 columns

Wszystko poszło dobrze, pozbyłem się 5 kolumn, wiec teraz czas na usuwanie duplikatów, zrobie to za pomocą drop.duplicates po prostu, powinno to teraz pozbyć sie rzędów w których sa te same dane, ponieważ już nic innego nie powinno powodować tu błędów.¶

In [32]:
food.shape
Out[32]:
(522652, 9)
In [33]:
food = food.drop_duplicates()
food.shape
Out[33]:
(272016, 9)
In [34]:
544032-272016
Out[34]:
272016

Z tego co widać dane były podwojone, jest to bardzo duża ilość, wiec bardzo dobrze, że to zostało zauważone, bo inaczej mogło by zakłamać wynik analizy.¶

Teraz można sprawdzić czy suma szystkich grup, daje taki sam wynik jak dla grupy wiekowej all.¶

In [35]:
food_all = food.loc[food['Gender'] == "All"]
food_all_oat = food_all.loc[food_all['FoodName'] == "Oat grain"]
food_all_oat_ch = food_all_oat.loc[food_all_oat['Country'] == "China"]
food_all_oat_ch.head(10)
Out[35]:
Country Year FoodCode FoodName AgeClass SourceAgeClass Gender Number_of_consumers Number_of_subjects
0 China 2002 A000G Oat grain All All All 1157 66172
812 China 2002 A000G Oat grain Infants and Toddlers 0-35 months All 10 838
1251 China 2002 A000G Oat grain Children and Adolescents 3-5 years All 20 2235
1782 China 2002 A000G Oat grain Children and Adolescents 6-14 years All 107 9844
2487 China 2002 A000G Oat grain Adults and Elderly 15-49 years All 545 33719
3267 China 2002 A000G Oat grain Adults and Elderly 50-74 years All 438 18143
4020 China 2002 A000G Oat grain Adults and Elderly >75 years All 37 1393
In [36]:
food_all_oat_ch['Number_of_consumers'].iloc[1:].sum()
Out[36]:
1157
In [37]:
food_all_oat_ch['Number_of_consumers'].iloc[0]
Out[37]:
1157

Wychodzi na to że wszystko sie zgadza, wiec czyszczenie danych sie powiodło, także czas na grupowanie i wizualizacje.¶

Tworzymy dataframes dla all, kobiet i mężczyzn, ale najpierw sprawdzam jak wyglądają dane w kolumnie gender.¶

In [38]:
food['Gender'].unique()
Out[38]:
array(['All', 'female', 'male', 'Female', 'Male'], dtype=object)

Jak widać dobrze, że sprawdziłem bo są tutaj dwie wersje Male i Female. Oznacza to, że muszę ujednolicić te dane i dla bezpieczeństwa zrobię to nie tylko w kolumnie gender.¶

In [39]:
# zrobie tak bo tylko 3 kolumny zmieniam
food.loc[:, 'Gender'] = food.loc[:, 'Gender'].str.title()
food.loc[:, 'FoodName'] = food.loc[:, 'FoodName'].str.title()
food.loc[:, 'Country'] = food.loc[:, 'Country'].str.title()
In [40]:
food['Gender'].unique()
Out[40]:
array(['All', 'Female', 'Male'], dtype=object)
In [41]:
food_all = food.loc[food['Gender'] == "All"]
food_fem = food.loc[food['Gender'] == "Female"]
food_men = food.loc[food['Gender'] == "Male"]

Zrobię też od razu rodzielenie na wszystkie grupy wiekowe.¶

In [42]:
food_all_all = food_all.loc[food_all['AgeClass'] == "All"]
food_fem_all = food_fem.loc[food_fem['AgeClass'] == "All"]
food_men_all = food_men.loc[food_men['AgeClass'] == "All"]
food_all_all.head()
Out[42]:
Country Year FoodCode FoodName AgeClass SourceAgeClass Gender Number_of_consumers Number_of_subjects
0 China 2002 A000G Oat Grain All All All 1157 66172
3 China 2002 A000N Buckwheat All All All 167 66172
6 China 2002 A000P Barley Grains All All All 61 66172
9 China 2002 A000T Maize Grain All All All 2422 66172
12 China 2002 A001B Common Millet Grain All All All 9069 66172
In [43]:
food_fem_all.head(5)
Out[43]:
Country Year FoodCode FoodName AgeClass SourceAgeClass Gender Number_of_consumers Number_of_subjects
1 China 2002 A000G Oat Grain All All Female 608 33953
4 China 2002 A000N Buckwheat All All Female 82 33953
7 China 2002 A000P Barley Grains All All Female 28 33953
10 China 2002 A000T Maize Grain All All Female 1355 33953
13 China 2002 A001B Common Millet Grain All All Female 4740 33953

Wszystko wygląda dobrze, wiec zajmę sie teraz sprawdzeniem z jakich krajów dane głównie były zbierane.¶

In [44]:
food_all_all['Country'].unique()
Out[44]:
array(['China', 'Republic Of Korea', 'United States Of America', 'Brazil',
       'Italy', "Lao People'S Democratic Republic", 'Mexico',
       'Mozambique', 'Malaysia', 'Nigeria', 'Pakistan', 'Philippines',
       'Burkina Faso', 'Bangladesh', 'Romania', 'Bulgaria', 'Uganda',
       'Bolivia (Plurinational State Of)', 'Zambia',
       'Democratic Republic Of The Congo', 'Ethiopia', 'Guatemala',
       'India'], dtype=object)
In [45]:
food_all_all['Country'].nunique()
Out[45]:
23
In [46]:
food['Country'].unique()
Out[46]:
array(['China', 'Republic Of Korea', 'Cyprus', 'Czech Republic',
       'Denmark', 'Finland', 'France', 'Greece', 'Hungary', 'Ireland',
       'Latvia', 'Netherlands', 'Portugal', 'Romania', 'Slovenia',
       'Spain', 'Sweden', 'United Kingdom', 'Austria', 'Belgium',
       'Bulgaria', 'Croatia', 'United States Of America', 'Brazil',
       'Italy', "Lao People'S Democratic Republic", 'Mexico',
       'Mozambique', 'Malaysia', 'Nigeria', 'Pakistan', 'Philippines',
       'Burkina Faso', 'Bangladesh', 'Uganda',
       'Bolivia (Plurinational State Of)', 'Zambia',
       'Democratic Republic Of The Congo', 'Ethiopia', 'Guatemala',
       'India'], dtype=object)
In [47]:
food['Country'].nunique()
Out[47]:
41
In [48]:
food_fem_all['Country'].nunique()
Out[48]:
23
In [49]:
food_men_all['Country'].nunique()
Out[49]:
14

Podczas sprawdzania z jakich krajów pochodzą dane zauważyłem, że nie zgadzają sie tu liczby krajów. W food były 41 ale już w food_all_all tylko 23 czyli brakuje tu 18 krajów.¶

In [50]:
null_data = food[food.isnull().any(axis=1)]
null_data.tail()
Out[50]:
Country Year FoodCode FoodName AgeClass SourceAgeClass Gender Number_of_consumers Number_of_subjects

Ale nie nie ma tu żadnych pustych danych, więc problem musi być z filtrowaniem, że nie wszystkie kraje mają AgeClass All. Dla przykładu sprawdzam Francje, której nie ma w food_all_all, a jest w food.¶

In [51]:
food_fr = food.loc[food['Country'] == "France"]
food_fr.head(10)
Out[51]:
Country Year FoodCode FoodName AgeClass SourceAgeClass Gender Number_of_consumers Number_of_subjects
37678 France 2007 A03MQ Shandy Children and Adolescents Other children Male 1 239
37679 France 2007 A03MX Wine, Red Children and Adolescents Other children Female 17 243
37680 France 2007 A03MX Wine, Red Children and Adolescents Other children Male 14 239
37681 France 2007 A03MV Wine, White Children and Adolescents Other children Female 19 243
37682 France 2007 A03MV Wine, White Children and Adolescents Other children Male 13 239
37683 France 2007 A03ND Cider Children and Adolescents Other children Female 3 243
37684 France 2007 A037V Pork Lard Children and Adolescents Other children Female 14 243
37685 France 2007 A037V Pork Lard Children and Adolescents Other children Male 9 239
37686 France 2007 A038G Duck Fat, Processed Children and Adolescents Other children Male 3 239
37687 France 2007 A038H Goose Fat, Processed Children and Adolescents Other children Female 14 243
In [52]:
food_fr['AgeClass'].unique()
Out[52]:
array(['Children and Adolescents', 'Adults and Elderly',
       'Infants and Toddlers'], dtype=object)
In [53]:
food_fr['Gender'].unique()
Out[53]:
array(['Male', 'Female', 'All'], dtype=object)
In [54]:
food['AgeClass'].unique()
Out[54]:
array(['All', 'Infants and Toddlers', 'Children and Adolescents',
       'Adults and Elderly'], dtype=object)
In [55]:
food_fr = food_fr.loc[food_fr['Gender'] == "All"] 
In [56]:
food_fr['Number_of_subjects'].unique().sum() # chyba to będzie rozwiązaniem
Out[56]:
8539

Tu się tylko potwierdza kwestia, tego że francja nie ma żadnej grupy podsumowaującej All czyli niektóre kraje też tak mają.¶

Oznacza to, że żeby móc przeanalizować z jakiego kraju jest najwiecej badanych muszę znaleźć inny sposób.¶

Sposobem na to może być wykorzystanie kolumn Country i Number_of_subjects. Zakładając, że każde badanie ma inną ilość badanych mogę zgrupować badanych i kraje, a następnie zsumować badanych, w ten sposób otrzymam ilość osób, które brały udział w badaniach z konkretnego kraju, nie musząc mieć AgeClass All. Ryzykiem tutaj jest jedynie to, że może zdarzyć się sytuacja, gdzie badania będą miały taką samą ilość badanych. Lecz na razie to rozwiązanie wydaje mi sie być najlepsze.¶

In [57]:
food_ctry = food_all.groupby(['Country','Number_of_subjects']).sum().reset_index()
food_ctry = food_ctry.groupby(['Country']).sum().reset_index()
food_ctry.loc[food_ctry['Country'] == "France"]
Out[57]:
Country Number_of_subjects Year FoodCode FoodName AgeClass SourceAgeClass Gender Number_of_consumers
15 France 8539 15546648 A036PA036VA037DA039CA03LGA03HGA03HHA032BA032CA... Olive OilsRape Seed Oil, EdibleSunflower Seed ... Infants and ToddlersInfants and ToddlersInfant... InfantsInfantsInfantsInfantsInfantsInfantsInfa... AllAllAllAllAllAllAllAllAllAllAllAllAllAllAllA... 503329

Jak widać na przykładzie francji ta operacja działa.¶

Dopiero w taki sposob moge to obejść i dzięki temu widze ile osob brało udział w badaniach z każdego kraju.¶

In [58]:
food_ctry = food_ctry.sort_values(by='Number_of_subjects', ascending=False)
In [59]:
food_ctry['Country'].nunique()
Out[59]:
41

Ilość krajów pozostała taka jak powinna, wiec nic nie zniknęło i mam podsumowane dobrze ilości badanych.¶

Do robienia wykresu zostawię tylko dwie kolumny oraz sprawdzę jaka była ilość badanych ze wszystkich krajów łącznie.¶

Wykres: Ilość badanych dla poszczególnych krajów.↑

In [60]:
most_sub_ctry = food_ctry[['Country','Number_of_subjects']]
most_sub_ctry.sum()
Out[60]:
Country               BrazilChinaUnited States Of AmericaRepublic Of...
Number_of_subjects                                               523051
dtype: object
In [61]:
px.bar(most_sub_ctry, x="Country", y="Number_of_subjects", title="Number of subjects per country", labels={'Number_of_subjects':'Number of subjects', 'Country': 'Countries' })

Na wykresie bardzo dobrze widać jak duża jest dysproporcja, co do ilości osób w zależności od kraju. Od razu wskazuje to, że wyciągnięte wnioski, mogą być zachwiane przez to, ile osób, w zależności od kraju było badanych, więc należy wziąć to pod uwagę.¶

Dla dokładności sprawdzę jak duża jest to różnica i jak rozkłada się to pod względem kontynentów.¶

In [62]:
top5 = most_sub_ctry['Number_of_subjects'].iloc[0:5].sum()
top5
Out[62]:
388340
In [63]:
rest = most_sub_ctry['Number_of_subjects'].iloc[5:].sum()
rest
Out[63]:
134711
In [64]:
top5/rest
Out[64]:
2.882763842596373

Jak widać top5 krajów ma prawie 3 razy wiecej badancyh niż reszta krajów, jest to bardzo duża dysporporcja zecz nie dyskredytuje to od razu analizy wszystkich danych.¶

Tworzenie kolumny z kodami i nazwami kontynentów. ↑

Rozbicie na kontynenty, pozwoli zobaczyć jak użyteczna będzie globalna analiza i czy nie lepiej będzie analizować, każdy kontynent odrębnie. Użyję do tego biblioteki pycountry_convert.¶

In [65]:
def convert(row): # funkcja przypisująca kod kontynentu w zależności od kraju
    cn_code = pc.country_name_to_country_alpha2(row.Country, cn_name_format="default")
    conti_code = pc.country_alpha2_to_continent_code(cn_code)
    return conti_code

Trzeba zamienić nazwy kilku krajów, bo biblioteka pycountry_convert korzysta z innych nazw krajów niż te które są w dataframe.¶

In [66]:
continent = food
ctry_change = {
	'Republic Of Korea' : 'South Korea',
    'Bolivia (Plurinational State Of)' : 'Bolivia',
    'United States Of America' : 'United States of America',
    "Lao People'S Democratic Republic" : "Lao People's Democratic Republic",
    "Democratic Republic Of The Congo" : "Democratic Republic of the Congo"
}
continent = continent.replace(ctry_change)
In [67]:
continent['ContinentCode'] = continent.apply(convert, axis=1)
continent
Out[67]:
Country Year FoodCode FoodName AgeClass SourceAgeClass Gender Number_of_consumers Number_of_subjects ContinentCode
0 China 2002 A000G Oat Grain All All All 1157 66172 AS
1 China 2002 A000G Oat Grain All All Female 608 33953 AS
2 China 2002 A000G Oat Grain All All Male 549 32219 AS
3 China 2002 A000N Buckwheat All All All 167 66172 AS
4 China 2002 A000N Buckwheat All All Female 82 33953 AS
... ... ... ... ... ... ... ... ... ... ...
272338 India 2015 A0EQN Soft Drinks With Minor Amounts Of Fruits Or Fl... All All Female 8 242 AS
272339 India 2015 A0EQN Soft Drinks With Minor Amounts Of Fruits Or Fl... Adults and Elderly 15-49 years All 8 242 AS
272340 India 2015 A0F4S Coconut Water All All All 7 242 AS
272341 India 2015 A0F4S Coconut Water Adults and Elderly 15-49 years Female 7 242 AS
272342 India 2015 A0F4S Coconut Water All All Female 7 242 AS

272016 rows × 10 columns

Mam kody kontynentów, wiec niby można by tak to zostawić ale uważam, że dużo ładniej i czytelniej jest jak będa też widoczne nazwy kontynentów.¶

In [68]:
continent['ContinentCode'].unique()
Out[68]:
array(['AS', 'EU', 'NA', 'SA', 'AF'], dtype=object)
In [69]:
conti_names = {	# stworzenie słownika dla kontynentów, żeby móc zamienić kody kontynentów na nazwy kontynentów
				'AS' : 'Asia',
				'EU' : 'Europe',
                'NA' : 'North America',
                'SA' : 'South America',
                'AF' : 'Africa'
                }
continent['Continent'] = continent['ContinentCode'].map(conti_names)
continent
Out[69]:
Country Year FoodCode FoodName AgeClass SourceAgeClass Gender Number_of_consumers Number_of_subjects ContinentCode Continent
0 China 2002 A000G Oat Grain All All All 1157 66172 AS Asia
1 China 2002 A000G Oat Grain All All Female 608 33953 AS Asia
2 China 2002 A000G Oat Grain All All Male 549 32219 AS Asia
3 China 2002 A000N Buckwheat All All All 167 66172 AS Asia
4 China 2002 A000N Buckwheat All All Female 82 33953 AS Asia
... ... ... ... ... ... ... ... ... ... ... ...
272338 India 2015 A0EQN Soft Drinks With Minor Amounts Of Fruits Or Fl... All All Female 8 242 AS Asia
272339 India 2015 A0EQN Soft Drinks With Minor Amounts Of Fruits Or Fl... Adults and Elderly 15-49 years All 8 242 AS Asia
272340 India 2015 A0F4S Coconut Water All All All 7 242 AS Asia
272341 India 2015 A0F4S Coconut Water Adults and Elderly 15-49 years Female 7 242 AS Asia
272342 India 2015 A0F4S Coconut Water All All Female 7 242 AS Asia

272016 rows × 11 columns

In [70]:
continent['Continent'].unique()
Out[70]:
array(['Asia', 'Europe', 'North America', 'South America', 'Africa'],
      dtype=object)

Jak widać wszystko ładnie się udało, wiec moge przypisać continent do food i ponownie stworzyć dataframes dla każdej płci.¶

In [71]:
food = continent
food_all = food.loc[food['Gender'] == "All"]
food_con = food_all.groupby(['ContinentCode','Number_of_subjects']).sum().reset_index()
food_con = food_con.groupby(['ContinentCode']).sum().reset_index()
food_con = food_con[['ContinentCode','Number_of_subjects']].sort_values(by='Number_of_subjects', ascending=False)
food_con = food_con.groupby(['ContinentCode']).sum().reset_index()
food_con.sum()
Out[71]:
ContinentCode         AFASEUNASA
Number_of_subjects        518734
dtype: object
In [72]:
most_sub_ctry.sum()
Out[72]:
Country               BrazilChinaUnited States Of AmericaRepublic Of...
Number_of_subjects                                               523051
dtype: object

Niestety ale robiąc to w ten sposob, tracę ponad 4000 badanych. Zbyt ważne jest rzeczywiste przedstawienie danych, żeby móc sobie pozwolić na taką stratę, tym bardziej nie wiedząć skąd konkretnie ona pochodzi, wiec wykonam to grupując najpierw kraje, a dopiero potem kontynenty. W ten sposób nie ma już ryzyka, że unikalne wartości ilości badanych dla krajów będą takie same, zbyt mała szansa jest na to.¶

In [73]:
food_ctry = food_all.groupby(['Country','Number_of_subjects']).sum().reset_index()
food_ctry = food_ctry.groupby(['Country']).sum().reset_index()
food_con = food_ctry.groupby(['ContinentCode','Number_of_subjects']).sum().reset_index()
food_con = food_con.groupby(['ContinentCode']).sum().reset_index()
food_con = food_con[['ContinentCode','Number_of_subjects']].sort_values(by='Number_of_subjects', ascending=False)

food_con.sum()
Out[73]:
ContinentCode         SASASASASASASASASASASASASASASASASASASASASASASA...
Number_of_subjects                                               523051
dtype: object

Otrzymany wynik jest taki sam jak w most_sub_ctry ale niestety kontynenty też są zgrupowane, wiec muszę odciać wszystko poza pierwszymi literami kodu, co pozwoli to dobrze podsumować.¶

In [74]:
food_con['ContinentCode'] = food_con['ContinentCode'].apply(lambda x: x[0:2])
food_con = food_con.groupby(['ContinentCode']).sum().reset_index().sort_values(by='Number_of_subjects', ascending=False)
food_con
Out[74]:
ContinentCode Number_of_subjects
1 AS 187248
4 SA 144248
2 EU 108344
3 NA 73032
0 AF 10179

Wszystko poszło dobrze, więc mogę teraz wizualizować, tylko jeszcze dodam nazwy kontynentów.¶

In [75]:
food_con['Continent'] = food_con['ContinentCode'].map(conti_names)
food_con
Out[75]:
ContinentCode Number_of_subjects Continent
1 AS 187248 Asia
4 SA 144248 South America
2 EU 108344 Europe
3 NA 73032 North America
0 AF 10179 Africa

Wykres: Procentowy udział badanych patrząc na kontynent. ↑

In [76]:
fig = px.pie(food_con, values='Number_of_subjects', names='Continent', title='Percent of subjects per Continents',color_discrete_sequence=px.colors.sequential.RdBu)
fig.show()

Na tym wykresie widać natomiast, że nie jest, aż tak złe rozłożenie badanych. Afryka wiadomo najgorzej wypada ale jednak reszta kontynentów względnie blisko siebie sie znajduje. Pozwala to jednak wyznaczyć ogólne trendy na świecie, co do spożywanych produktów. Gdyby nie sprawdzić tego, jak wygląda rozłożenie na kontynenty, łatwo by można uznać, że nie jest warte robienie globalnej analizy tylko dokładnej dla kraju lub kontynentu.¶

Teraz natomiast zajmę sie takim przygotowaniem danych, żeby móc wygodnie przeanalizować najbardziej spożywane produkty, ponieważ nie wszędzie jest AgeClass dla All, wiec inny sposob muszę znaleźć. Będę to wstepnie robić na Oat Grain dla Włoch.¶

In [77]:
it_oat_all = food_all.loc[food_all['FoodName'] == "Oat Grain"]
it_oat_all = it_oat_all.loc[it_oat_all['Country'] == "Italy"]
it_oat_all
Out[77]:
Country Year FoodCode FoodName AgeClass SourceAgeClass Gender Number_of_consumers Number_of_subjects ContinentCode Continent
212154 Italy 2006 A000G Oat Grain All All All 4 3307 EU Europe
212169 Italy 2006 A000G Oat Grain Infants and Toddlers 0-35 months All 0 36 EU Europe
212170 Italy 2006 A000G Oat Grain Children and Adolescents 3-5 years All 0 67 EU Europe
212171 Italy 2006 A000G Oat Grain Children and Adolescents 6-14 years All 0 284 EU Europe
212172 Italy 2006 A000G Oat Grain Adults and Elderly 15-49 years All 2 1603 EU Europe
212173 Italy 2006 A000G Oat Grain Adults and Elderly 50-74 years All 2 1089 EU Europe
212174 Italy 2006 A000G Oat Grain Adults and Elderly >75 years All 0 228 EU Europe
In [78]:
it_oat_all[1:].groupby(['Country','FoodName']).sum().reset_index() # sprawdzam czy suma wartości bez SourceAgeClass=All są równe All
Out[78]:
Country FoodName Year FoodCode AgeClass SourceAgeClass Gender Number_of_consumers Number_of_subjects ContinentCode Continent
0 Italy Oat Grain 12036 A000GA000GA000GA000GA000GA000G Infants and ToddlersChildren and AdolescentsCh... 0-35 months3-5 years6-14 years15-49 years50-74... AllAllAllAllAllAll 4 3307 EUEUEUEUEUEU EuropeEuropeEuropeEuropeEuropeEurope

Chyba najlepiej bedzie pozbyć się rzędu dla SourceAgeClass w którym jest All i potem podsumować.¶

In [79]:
# tworzę maskę która zawiera rzędy z All
mask = it_oat_all['AgeClass'] == 'All'

# używając ~ i maski pozbywam się z it_oat_all tego co zawiera maska
it_oat_all = it_oat_all[~mask]
it_oat_all
Out[79]:
Country Year FoodCode FoodName AgeClass SourceAgeClass Gender Number_of_consumers Number_of_subjects ContinentCode Continent
212169 Italy 2006 A000G Oat Grain Infants and Toddlers 0-35 months All 0 36 EU Europe
212170 Italy 2006 A000G Oat Grain Children and Adolescents 3-5 years All 0 67 EU Europe
212171 Italy 2006 A000G Oat Grain Children and Adolescents 6-14 years All 0 284 EU Europe
212172 Italy 2006 A000G Oat Grain Adults and Elderly 15-49 years All 2 1603 EU Europe
212173 Italy 2006 A000G Oat Grain Adults and Elderly 50-74 years All 2 1089 EU Europe
212174 Italy 2006 A000G Oat Grain Adults and Elderly >75 years All 0 228 EU Europe

Widać, że ta metoda zadziałała, wiec muszę wykonać to na podstawowej dataframe i potem podzielić na płcie.¶

In [80]:
mask = food['AgeClass']== 'All'
food = food[~mask]
In [81]:
food_all = food.loc[food['Gender'] == "All"]
food_fem = food.loc[food['Gender'] == "Female"]
food_men = food.loc[food['Gender'] == "Male"]
In [82]:
most_consumed_all = food_all.groupby(['FoodName']).sum().reset_index().sort_values(by='Number_of_consumers', ascending=False)
most_consumed_fem = food_fem.groupby(['FoodName']).sum().reset_index().sort_values(by='Number_of_consumers', ascending=False)
most_consumed_men = food_men.groupby(['FoodName']).sum().reset_index().sort_values(by='Number_of_consumers', ascending=False)
most_consumed_all[['FoodName','Number_of_consumers']].head(10)
Out[82]:
FoodName Number_of_consumers
1 (All Cereals) 142214
2811 Wheat Bread And Rolls, White (Refined Flour) 135436
1836 Onions 112344
2249 Rice Grain, Polished 105857
1997 Pig Fresh Meat 104118
2652 Tap Water 92605
2092 Potatoes 89154
375 Carrots 87843
1126 Garlic 84415
2243 Rice Grain 82719

📊 Wykres: Najpopularniejsze produkty na świecie. ↑

In [83]:
show_most_consumed_all = most_consumed_all.head(30)
px.bar(show_most_consumed_all, x="FoodName", y="Number_of_consumers", title="Most popular foods in the World", labels={'Number_of_consumers':'Number of comsumers', 'FoodName': 'Food Names' })

Na wykresie widzimy, że najpopularniejszym jedzeniem na świecie są płatki śniadaniowe. Wiadomo, że jest to zebranie wszystkich rodzajów płatków, ale nadal jest to niesamowite, że przebija to nawet najpopularniejsze warzywa albo zioła, które ludzie wydawałoby się dodają do wszystkiego, takie jak np cebula, czosnek lub pieprz. Jako, że płatki śniadaniowe nie są najzdrowszym produktem, to może być to martwiąca informacja tym bardziej, że na drugim miejscu jest białe pieczywo. Te dwa produkty wskazują, że ludzie bardzo lubią proste produkty, łatwe i szybkie w przygotowaniu w szczególnosci, jeżeli chodzi o śniadania, bo jednak to z tym głownie kojarzą sie płatki i pieczywo.¶

Na szczęście później dzieje sie lepiej, cebula, ryż (nadal biały łuskany ale jednak zawiera on odpowiednie aminokwasy, nie ma tłuszczu ani cukru), co ciekawe wieprzowina jest na 5 miejscu, zazwyczaj wydaje się, że to kurczak króluje jako mięso, ale na szczęście dane nie wiedzą co to błędne myślenie.¶

Informacje z wykresu, które pomogły by z tworzeniem menu do restauracji, mogą być podzielone na dwie grupy.¶

Pierwsza czyli dla restauracji serwująca proste, domowe, lokalne jedzenie. W takim wypadku stawianie na produkty i dania które ludzie znają i czują sie z nimi bezpiecznie oraz są szybkie do zaserwowania są idealne. W takich miejscach ludzie nie szukają nowości a na pewno nie jest to głownym celem wiec użycie tych najpopularniejszych produktów pozwoli zadowolic takich klientów¶

Druga czyli dla restauracji wykwintnej lub zajmującej się klientami, którzy szukają czegoś nowego. Wtedy, dobrym krokiem będzie wykorzystanie klasycznych technik do przedstawienia zupelnie nowych lub niespotykanych produktów i zaaranzowanie ich z tymi znanymi i powoli pokazywanie czegoś nowego. To z domem i codziennością kojarzą sie proste dania, a te nowe, niespodziewane, wyjątkowe z czymś za co warto zapłacić więcej.¶

Ogólnym wnioskiem, który można wyciągnąć z tych danych jest to, że górują proste produkty oraz widać tu wymieszanie wielu kultur.¶

Sprawdzę jeszcze jak różni się Europa, od danych z całego Świata.¶

📊 Wykres: Najpopularniejsze produkty w Europie. ↑

In [84]:
food_all = food.loc[food['Gender'] == "All"]
food_all_eu = food_all.loc[food_all['Continent'] == "Europe"]
most_consumed_all_eu = food_all_eu.groupby(['FoodName']).sum().reset_index().sort_values(by='Number_of_consumers', ascending=False)
most_consumed_all_eu = most_consumed_all_eu.head(30)

px.bar(most_consumed_all_eu, x="FoodName", y="Number_of_consumers", title="Most popular food in Europe", labels={'Number_of_consumers':'Number of comsumers', 'FoodName': 'Food Names' })

Gdy tylko przełączę dane na Europę widać różnice w pierwszym produkcie, nie ma tu płatków śniadaniowych tylko woda z kranu. Może wynikać to z tego, bezpieczeństwo picia wody z kranu w Europie jest na dużo wyższym poziomie [3] oraz że były kampanie zachęcające do picia wody z kranu (w Polsce również je mieliśmy). Drugie miejsce Bez zmian, białe pieczywo króluje (zapewne nie bez winy jest tu Francja) ale potem znowu robi się ciekawie, cebula, marchew, masło czyli podstawy większości dań i sosów Europejskich takich jak risotto, rosół, Ragù alla bolognese, sosu demi glace i wiele innych. Również mięso z kurczaka znajduje się wyżej od wieprzowego.¶

Mleko które też jak widać częściej jest spożywane w Europie niż w reszcie świata, a w szczególności Azji [4]. Niepokojącą rzeczą jest natomiast wysokie miejsce margaryny(poprzez tradycyjną rozumiem utwardzoną czyli tą zawierającą tłuszcze trans) oraz soli i cukru które wpływają na ciśnienie tętnicze [5]. Dużo dalej znajduje sie natomiast ryż, widać że dużo mniej go spożywamy. Też niebezpieczna rzeczą jest to, że rozdzielona jest sól na jodowaną i niejdowaną co znaczy, że sól jest jeszcze na wyższym miejscu. Również wysokie miejsce pomidorów, czosnku i oliwy z oliwek pokazuje duży wpływ kuchni włoskiej, ogólnie na podstwie tego wykresu można zauważyć duży wpływ kuchni włoskiej i francuskiej na europę.¶

Ten wykres pokazuje to samo co poprzedni, ludzie najbardziej lubią klasyki i proste produkty, wiec menu zależy od profilu restauracji. Dane wskazują na to, że nie bez powodu jest tak dużo restauracji z kuchnią francuską i włoską. Ludzie to uwielbiają.¶

📊 Wykresy: Najpopularniejsze produkty u mężczyzn i kobiet. ↑

In [85]:
show_most_consumed_men = most_consumed_men.head(15)
show_most_consumed_fem = most_consumed_fem.head(15)
first_line = go.Bar(x=show_most_consumed_men["FoodName"], y=show_most_consumed_men["Number_of_consumers"], name="Male")
second_line = go.Bar(x=show_most_consumed_fem["FoodName"], y=show_most_consumed_fem["Number_of_consumers"], name="Female")
fig = make_subplots(rows=1, cols=2)
fig.add_trace(first_line,row=1, col=1)
fig.add_trace(second_line,row=1, col=2)
fig.update_layout(title_text="Most popular foods for men and women")
fig.show()

Sprawdzenie jaki procent kobiet i mężczyzn spożywa płatki śniadaniowe.¶

In [86]:
show_most_consumed_fem[:1]['Number_of_consumers']/food_fem['Number_of_subjects'].unique().sum()*100
Out[86]:
1   49.22
Name: Number_of_consumers, dtype: float64
In [87]:
show_most_consumed_men[:1]['Number_of_consumers']/food_men['Number_of_subjects'].unique().sum()*100
Out[87]:
2694   48.40
Name: Number_of_consumers, dtype: float64

Prównuja konsumpcje mężczyzn i kobiet dwie rzeczy najbardziej rzucają mi sie w oczy, pierwsza że płatki u obu płci są na pierwszym miejscu, chociaż co ciekawe kobiety jedza o 0.59 pkt% wiecej płatków od mężczyzn. Druga, że u kobiet warzywa są na 3 miejscu a u mężczyzn na 6, najprawdopodobniej wynika to z tego, że kobiety prędzej są na diecie wegeteriańskiej lub wegańskiej, plus społecznie przyjmuje się, że mężczyzni wiecej miesa powinni spożywać tak jak wskazuje to badanie [6], ale dla dokładnej analizy tego zjawiska przydałoby sie wiecej danych, ponieważ może to wynikać np z tego że organizm mężczyzn rzeczywiście potrzebuje wiecej mięsa np przez kreatynę które ono dostarcza. Również mięso wieprzowe u mężczyzn jest na wyższym miejscu.¶

Na podstawie tego co piszę można by wywnioskować, że kobiety mają zdrowszą diete ale jednak nie można tak od razu zrobić, ponieważ po pierwsze te płatki których jednak wiecej spożywają ale również to że do top10 u kobiet załapuje sie cukier, a u mężczyzn nie, oraz że tłuszcze u kobiet zajmują wyższe miejce. Na podstawie tego widać, że nie jest to takie proste, istnieje możliwość, że z powodu trzymania zdrowszej diety jeżeli chodzi o np obiady to w przypadku przekąsek, a w szczególości tych słodkich i tłustych to kobiety ich wiecej spożywają. Może to wskazywać na prostą zależność, że ludzie naturalnie szukają równowagi.¶

Jeżeli chodzi o wnioski, które by pomogły w tworzeniu odpowiedniego menu do restauracji są takie same jak przy wcześniejszych wykresach, ale jeżeli chodzi o profilowanie restauracji pod kobiety lub mężczyzn należy pamiętać o tym, że widać częściej spożywany cukier i tłuszcze przez kobiety. Znaczy to że cukiernia reklamowana dla kobiet będzie dobrym pomysłem.¶

Tak samo w przypadku mężczyzn dobrym pomysłem byłaby restauracja związana z mięsem. i raczej wytrawnymi daniami.¶

Wykresy: najpopularniejsze produkty dla mężczyzn i kobiet w Europie. ↑

In [88]:
food_fem_eu = food_fem.loc[food_fem['Continent'] == "Europe"]
food_men_eu = food_men.loc[food_men['Continent'] == "Europe"]
most_consumed_fem_eu = food_fem_eu.groupby(['FoodName']).sum().reset_index().sort_values(by='Number_of_consumers', ascending=False)
most_consumed_men_eu = food_men_eu.groupby(['FoodName']).sum().reset_index().sort_values(by='Number_of_consumers', ascending=False)


show_most_consumed_men_eu = most_consumed_men_eu.head(15)
show_most_consumed_fem_eu = most_consumed_fem_eu.head(15)

first_line = go.Bar(x=show_most_consumed_men_eu["FoodName"], y=show_most_consumed_men_eu["Number_of_consumers"], name="Male")
second_line = go.Bar(x=show_most_consumed_fem_eu["FoodName"], y=show_most_consumed_fem_eu["Number_of_consumers"], name="Female")
fig = make_subplots(rows=1, cols=2)
fig.add_trace(first_line,row=1, col=1)
fig.add_trace(second_line,row=1, col=2)
fig.update_layout(title_text="Most popular foods for men and women in EU")
fig.show()

↑Wnioski: W Europie w różnicach między płciami jest inaczej niż na świecie. Mięso z kurczaka jest na tym samym miejscu co ciekawe, jedynie mieso wieprzowe wypada z top15 u kobiet czyli nadal tendencja, że mężczyźni jedzą wiecej mięsa jest prawdziwa ale nie w przypadku kurczaka. Poza tym nie ma tu zbyt ciekawych różnic. Czyżby to wskazywało, że otwartość i różnorodność Europy wpływa na upodobnienia się kobiet i mężczyzn w sferze jedzeniowej? W końcu pierwsze mięso u mężczyzn spadło z 4 miejsca na 6. Ale jeszcze ważna informacja sie tu kryje, to że sól u kobiet jest wyżej.

Podsumowanie 🧠 ↑

Jak widać nawet w bazach danych branych z źródeł, które wydawały by się, że mają je bardzo dobrze wyczyszczone i że są bez błędów, to nadal one mogą je zawierać i nie należy brać za pewnik, że wszystko bedzie dobrze, zawsze samemu należy to sprawdzać, bo błędy mogą wszędzie się kryć. Czasem można iść na kompromis ale nic nie zastąpi dobrej, czystej bazy danych i wiedzy o każdej kolumnie i co ona pokazuje.¶

Z uporządkowanych danych dało się wywnioskować to, że:¶

  1. zupełnie inaczej ludzie w różnych częściach globu się odżywiają ale niektóre produkty się przeplatają,
  2. mężczyźni spożywają wiecej mięsa i słonych rzeczy, a kobiety więcej warzyw i słodyczy,
  3. w Europie jest duże zaufanie co do kranówki,
  4. mleko w Europie jest częściej spożywane niż w reszcie świata,
  5. wieprzowina na świecie króluje nad kurczakiem, a w Europie jest odwrotnie,
  6. świat spożywa na prawde dużo płatków śniadaniowych,
  7. w Europie jest mniejsza różnica w diecie obu płci niż jest to na świecie,
  8. raczej są dwa typy menu można stworzyć, z klasycznym jedzeniem oraz nowatorskim ### Mam nadzieję, że była to przyjemna lektura i pokazała ciekawe zależności w świecie jedzenia. Do zobaczenia.

Możliwe zakłamania: ⚠️↑

  1. Założenie przeze mnie, że każde badanie ma różną ilość badanych i w ten sposób grupowanie badanych
  2. Brak grupy wiekowej All
  3. Własne opinie i przeświadczenia
  4. Brak legendy do bazy danych

Źródła:📱 ↑

  1. Gif: https://www.slynyrd.com/blog/2020/9/30/pixelblog-30-food
  2. Baza danych: https://apps.who.int/foscollab/Download/DownloadConso
  3. Dane na temat jakości wody na świecie: https://worldpopulationreview.com/country-rankings/water-quality-by-country
    1. https://vividmaps.com/tap-water-safe-to-drink/
  4. Badanie na temat różnicy konsumpcji warzyw między płciami: https://www.ncbi.nlm.nih.gov/pmc/articles/PMC3490048/
  5. Badania na temat wpływu soli i cukru na ciśnienie tętnicze: https://sci-hub.se/10.1007/s00424-014-1677-x
    1. https://www.ncbi.nlm.nih.gov/pmc/articles/PMC4896734/
    2. https://www.ncbi.nlm.nih.gov/pmc/articles/PMC6770596/
  6. Dane na temat nietolerancji laktozy na świecie: https://worldpopulationreview.com/country-rankings/lactose-intolerance-by-country